#include "../../src/util/websocket/websocket_impl.hh"
#include "../framework/unittest.hh"
#include <fstream>

FIXTURE_BEGIN(test_websocket)

using namespace kratos;

/*

HTML file: index.html

<html>
    <body>
        <script src='./index.js'></script>
    </body>
</html>

Javascript file: index.js

let ws = new WebSocket('ws://localhost:8888')

ws.onopen = () => {
    console.log('open connection successfully')
    return true;
}

ws.onclose = () => {
    console.log('close connection')
}

ws.onmessage = function (e) {
    if (e.data instanceof Blob) {
        var reader = new FileReader();
        reader.onload = () => {
            console.log("Result: " + reader.result.length);
            ws.send(reader.result);
        };
        reader.readAsText(e.data);
    } else {
        console.log("Result: " + e.data.length);
        ws.send(e.data);
    }
};

ws.onerror = function(event) {
    console.error("WebSocket error observed:", event);
};


*/

SETUP([]() {

});

struct Cb1 {
  bool done{false};
  bool close{false};
  char buffer_127[127];
  char buffer_128[128];
  char buffer_256[256];
  char buffer_1024[1024];
  char buffer_65535[65535];
  bool buffer_127_n{false};
  bool buffer_65535_n{false};
  Cb1() {
    memset(buffer_127, '1', sizeof(buffer_127));
    memset(buffer_128, '1', sizeof(buffer_128));
    memset(buffer_256, '1', sizeof(buffer_256));
    memset(buffer_1024, '1', sizeof(buffer_1024));
    memset(buffer_65535, '1', sizeof(buffer_65535));
  }
  void cb(kratos::ws::WebSocketEvent e,
          kratos::ws::WebSocketChannelPtr channel) {
    if (e == kratos::ws::WebSocketEvent::ACCEPT) {
      channel->send("world");
      channel->send(buffer_128, sizeof(buffer_128));
      channel->send(buffer_256, sizeof(buffer_256));
      channel->send(buffer_127, sizeof(buffer_127));
      channel->send(buffer_1024, sizeof(buffer_1024));
      channel->send(buffer_65535, sizeof(buffer_65535));
    } else if (e == kratos::ws::WebSocketEvent::RECV) {
      if (channel->size() == sizeof(buffer_127)) {
        buffer_127_n = true;
      }
      if (channel->size() == sizeof(buffer_65535)) {
        buffer_65535_n = true;
      }
      std::cout << channel->size() << std::endl;
      std::string s;
      channel->recv(s);
    } else if (e == kratos::ws::WebSocketEvent::CLOSE) {
      close = true;
    }
  }
};

CASE(TestWebSocket1) {
  auto* cb1 = new Cb1();
  kratos::ws::WebSocketServerImpl server(nullptr);
  server.startup(std::bind(&Cb1::cb, cb1, std::placeholders::_1, std::placeholders::_2));
  server.listen_at("ws", "127.0.0.1", 8888);
  while (!cb1->buffer_65535_n || !cb1->buffer_127_n) {
    std::this_thread::sleep_for(std::chrono::milliseconds(1));
    server.update();
  }
  server.shutdown();
  delete cb1;
}

TEARDOWN([]() {
});

FIXTURE_END(test_websocket)
